#ifndef CPU_H
#define CPU_H

#include "comm/types.h"

// 注意这些参数是对应的 gdt 表的设置函数的
#define SEG_G				(1 << 15)		// 设置段界限的单位，1-4KB，0-字节
#define SEG_D				(1 << 14)		// 控制是否是32位、16位的代码或数据段
#define SEG_P_PRESENT	    (1 << 7)		// 段是否存在

#define SEG_DPL0			(0 << 5)		// 特权级0，最高特权级
#define SEG_DPL3			(3 << 5)		// 特权级3，最低权限

#define SEG_S_SYSTEM		(0 << 4)		// 是否是系统段，如调用门或者中断
#define SEG_S_NORMAL		(1 << 4)		// 普通的代码段或数据段

#define SEG_TYPE_CODE		(1 << 3)		// 指定其为代码段
#define SEG_TYPE_DATA		(0 << 3)		// 数据段

#define SEG_TYPE_RW			(1 << 1)		// 是否可写可读，不设置为只读



#pragma pack(1)

/**
 * GDT描述符
 */
// 这是gdt 表的模板
typedef struct _segment_desc_t {
	uint16_t limit15_0;
	uint16_t base15_0;
	uint8_t base23_16;
	uint16_t attr;   //注意这里面是有 16：19 的 limit 的值的。
	uint8_t base31_24;
}segment_desc_t;

#pragma pack()

// 这是c 文件中的两个函数
void cpu_init (void);
void segment_desc_set(int selector, uint32_t base, uint32_t limit, uint16_t attr);

#endif
